/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/**
 * \file
 * \brief Top level GIMnet protocol handler (dispatcher) - implementation.
 * \author Antti Maula <antti.maula@tkk.fi>
 */
#include "protocol.h"
#include "owndebug.h"
#include <assert.h>
#include <stdlib.h>

//*****************************************************************************
//*****************************************************************************
static TProtocol globalProtocol;
//*****************************************************************************

int protocolInit()
{
  int i;
  TProtocol *p = &globalProtocol;

  // Initialize all protocol entries to NULL initially
  for(i=0; i < MAX_PROTOCOL_COUNT; i++) {
    p->entrytable[i] = NULL;
  }
  
  return 0;
}
//*****************************************************************************

int protocolDeinit()
{
  //  TProtocol *p = &globalProtocol;
  return 0;
}
//*****************************************************************************

int protocolRegisterProtocol(int protocol_number, const TProtocolEntry *entry)
{
  int result;
  TProtocol *p = &globalProtocol;

  // Trivials
  assert( p != NULL ); 
  assert( entry != NULL );
  assert( protocol_number >= 0 && protocol_number < MAX_PROTOCOL_COUNT );
  
  // Add entry to protocol table (if not previously assigned)
  if (p->entrytable[protocol_number] == NULL) {
    p->entrytable[protocol_number] = entry;
    dPrintG(3,"Successfully registered protocol '%02x'", protocol_number); 
    result = 0;
 
  } else {
    dPrintG(1,"WARNING: Tried to re-register protocol '%02x'! Ignored.", protocol_number);
    result = -1;
  
  }
  
  return result;
}
//*****************************************************************************

const TProtocolEntry *protocolGetProtocolEntry(int protocol_number)
{  
  TProtocol *p = &globalProtocol;

  // Trivials
  assert( p != NULL ); 
  assert( protocol_number >= 0 && protocol_number < MAX_PROTOCOL_COUNT );

  // Get entry
  return p->entrytable[protocol_number];
}
//*****************************************************************************

void protocolEntryDestroy(TProtocolEntry *pe)
{
  free(pe);
}
//*****************************************************************************

TProtocolEntry *protocolEntryConstructNew(int number,
					  void *pData,
					  protocolRawHandlerPtr protocolRawHandler,
					  protocolHandlerPtr protocolHandler,
					  protocolErrorHandlerPtr protocolErrorHandler)
{
  TProtocolEntry *ne = (TProtocolEntry *)malloc(sizeof(TProtocolEntry));
  assert (ne != NULL);

  protocolEntryConstruct(ne, number, pData, 
			 protocolRawHandler,
			 protocolHandler, 
			 protocolErrorHandler);
  
  return ne;
}
//*****************************************************************************
     
void protocolEntryConstruct(TProtocolEntry *pe,
			    int number,
			    void *pData,
			    protocolRawHandlerPtr protocolRawHandler,
			    protocolHandlerPtr protocolHandler,
			    protocolErrorHandlerPtr protocolErrorHandler)
{
  // Trivial
  assert(pe != NULL);

  // Assignments
  pe->protocol_number = number;
  pe->protocolData = pData;
  pe->protocolRawHandler = protocolRawHandler;
  pe->protocolHandler = protocolHandler;
  pe->protocolErrorHandler = protocolErrorHandler;
}
//*****************************************************************************
//*****************************************************************************
//*****************************************************************************
//*****************************************************************************
//*****************************************************************************
//*****************************************************************************
//*****************************************************************************
